package com.anlu.alspringmvc.spring.framework.webmvc.servlet;

import com.anlu.alspringmvc.spring.framework.annotation.ALRequestParam;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Administrator
 */
public class ALHanderAdapter {

    public ALModelAndView handler(HttpServletRequest req, HttpServletResponse resp, ALHandlerMapping handler) throws InvocationTargetException, IllegalAccessException {
        //将参数名称和参数的位置，这种关系保存起来
        Map<String, Integer> paramIndexMapping = new HashMap<>();
        //通过运行时的状态拿到注解
        Annotation[][] pa = handler.getMethod().getParameterAnnotations();

        for (int i = 0; i < pa.length; i++) {
            for (Annotation a : pa[i]) {
                if (a instanceof ALRequestParam) {
                    String paramName = ((ALRequestParam) a).value();
                    if (!"".equals(paramName.trim())) {
//                        String value = Arrays.toString(params.get(paramName))
//                                .replaceAll("\\[|\\]","")
//                                .replaceAll("\\s+",",");
//                        paramValues[i] = value;
                        paramIndexMapping.put(paramName, i);
                    }
                }
            }
        }

        //初始化一下
        Class<?>[] paramTypes = handler.getMethod().getParameterTypes();
        for(int i = 0; i < paramTypes.length; i++){
            Class<?> paramType = paramTypes[i];
            if(paramType == HttpServletRequest.class || paramType == HttpServletResponse.class){
                paramIndexMapping.put(paramType.getName(),i);
            }
        }

        //去拼接实参列表
        //http://localhost/web/query?name=Tom&Cat
        Map<String,String[]> params = req.getParameterMap();

        Object[] paramValues = new Object[paramTypes.length];
        for (Map.Entry<String, String[]> stringEntry : params.entrySet()) {
            String value = Arrays.toString(params.get(stringEntry.getKey()))
                    .replaceAll("\\[|\\]","")
                    .replaceAll("\\s+",",");
            if(!paramIndexMapping.containsKey(stringEntry.getKey())){
                continue;
            }

            int index = paramIndexMapping.get(stringEntry.getKey());
            //允许自定义类型转换器 Converter
            paramValues[index] = castStringValue(value, paramTypes[index]);
        }

        if(paramIndexMapping.containsKey(HttpServletRequest.class.getName())){
            int index = paramIndexMapping.get(HttpServletRequest.class.getName());
            paramValues[index] = req;
        }
        if(paramIndexMapping.containsKey(HttpServletResponse.class.getName())){
            int index = paramIndexMapping.get(HttpServletResponse.class.getName());
            paramValues[index] = resp;
        }

        Object result = handler.getMethod().invoke(handler.getController(),paramValues);
        if(result == null || result instanceof Void){
            return null;
        }
        boolean isModelAndView = handler.getMethod().getReturnType() == ALModelAndView.class;
        if(isModelAndView){
            return (ALModelAndView) result;
        }
        return null;
    }

    private Object castStringValue(String value, Class<?> paramType) {
        if(String.class == paramType){
            return value;
        }else if(Integer.class == paramType){
            return Integer.valueOf(value);
        }else if(Double.class == paramType){
            return Double.valueOf(value);
        }else {
            if(value != null){
                return value;
            }
            return null;
        }

    }
}
